home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / Snippets / Toolbox & IAC / ◊Other / WDEFPatch / wdefpatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  6.5 KB  |  323 lines  |  [TEXT/KAHL]

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ©1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.  
  11. *******************************************/
  12.  
  13. #include <Windows.h>
  14.  
  15. /* add 2 to this when checking with FindWindow() ! */
  16.  
  17. #define kOurHit    32
  18.  
  19. Boolean gInBackground;
  20. Boolean gDone;
  21.  
  22. void InitStuff(void);
  23. void EventLoop(WindowPtr window);
  24. void DoDrag(WindowPtr window,Point globMouse);
  25. void HandleMouseDowns(EventRecord *ev);
  26. void HandleContent(WindowPtr theWindow,EventRecord *ev);
  27. void HandleUpdates(WindowPtr wind);
  28. void DoDeActivate(WindowPtr window,Boolean chFlag);
  29. void DoActivate(WindowPtr window,Boolean chFlag);
  30. void HandleActivates(EventRecord *ev);
  31. void HandleSREvt(long message);
  32. void DoGrow(WindowPtr window,Point globMouse);
  33. void PatchWindowWDEF(WindowPtr window);
  34. pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param);
  35. void HandleOurPart(WindowPtr window);
  36.  
  37.  
  38. /* this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  39.     and stores the old handle to the WDEF
  40. */
  41.  
  42. typedef struct {
  43.     short jmpInst;
  44.     ProcPtr patchAddr;
  45.     Handle oldAddr;
  46. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  47.  
  48.  
  49. void main(void)
  50. {
  51.     WindowPtr mainWindow;
  52.     Rect bounds = {100,100,150,300};
  53.     
  54.     gInBackground = false;
  55.     gDone = false;
  56.     
  57.     InitStuff();
  58.     mainWindow = NewWindow(nil,&bounds,"\pWDEF Patcher",false,documentProc,(WindowPtr)-1,true,0);
  59.     PatchWindowWDEF(mainWindow);
  60.     ShowWindow(mainWindow);
  61.     EventLoop(mainWindow);
  62. }
  63.  
  64.  
  65. void InitStuff(void)
  66. {
  67.     InitGraf(&qd.thePort);
  68.     InitFonts();
  69.     InitWindows();
  70.     InitMenus();
  71.     TEInit();
  72.     InitDialogs(nil);
  73.     InitCursor();
  74.     FlushEvents(everyEvent,0);
  75. }
  76.  
  77.  
  78. void EventLoop(WindowPtr window)
  79. {
  80.     EventRecord ev;
  81.     
  82.     do {
  83.         if (WaitNextEvent(everyEvent,&ev,10,nil)) {
  84.             switch (ev.what) {
  85.                 case mouseDown:
  86.                     HandleMouseDowns(&ev);
  87.                     break;
  88.                 case updateEvt:
  89.                     HandleUpdates((WindowPtr)ev.message);
  90.                     break;
  91.                 case activateEvt:
  92.                     HandleActivates(&ev);
  93.                     break;
  94.                 case app4Evt:
  95.                     HandleSREvt(ev.message);
  96.                     break;
  97.             }
  98.         }
  99.     } while (!gDone);
  100. }
  101.  
  102.  
  103. void HandleMouseDowns(EventRecord *ev)
  104. {
  105.     WindowPtr theWindow;
  106.     short part;
  107.     
  108.     part = FindWindow(ev->where,&theWindow);
  109.  
  110.     switch (FindWindow(ev->where,&theWindow)) {
  111.         case inMenuBar:
  112.             break;
  113.         case inSysWindow:
  114.             SystemClick(ev,theWindow);
  115.             break;
  116.         case inDrag:
  117.             DoDrag(theWindow,ev->where);
  118.             break;
  119.         case inGoAway:
  120.             if (TrackGoAway(theWindow,ev->where)) {
  121.                 gDone = true;
  122.             }
  123.             break;
  124.         case inContent:
  125.             HandleContent(theWindow,ev);
  126.             break;
  127.         case inGrow:
  128.             DoGrow(theWindow,ev->where);
  129.             break;
  130.         case kOurHit+2:                        // remember, we're adding 2 so the FindWindow/WDEF
  131.             HandleOurPart(theWindow);        // codes match
  132.             break;
  133.     }
  134. }
  135.  
  136.  
  137.  
  138. /* handles a mouse down in our added window part */
  139.  
  140. void HandleOurPart(WindowPtr window)
  141. {
  142.     long final;
  143.     
  144.     SetPort(window);
  145.     InvertRect(&window->portRect);
  146.     while (StillDown());
  147.     InvertRect(&window->portRect);
  148. }
  149.  
  150.  
  151. /* DoDrag: Handles drag window events */
  152.  
  153. void DoDrag(WindowPtr window,Point globMouse)
  154. {
  155.     Rect dragRect;
  156.     
  157.     SetRect(&dragRect,-32000,-32000,32000,32000);
  158.     
  159.     DragWindow(window,globMouse,&dragRect);
  160.     SetPort(window);
  161. }
  162.  
  163.  
  164. /* DoGrow: Handles grow window events */
  165.  
  166. void DoGrow(WindowPtr window,Point globMouse)
  167. {
  168.     long newSize;
  169.     Rect windLimits;
  170.     GrafPtr tempPort;
  171.     
  172.     SetRect(&windLimits,64,64,32000,32000);
  173.     
  174.     if ((newSize = GrowWindow(window,globMouse,&windLimits)) != 0) {
  175.         GetPort(&tempPort);
  176.         SetPort(window);
  177.         SizeWindow(window,LoWord(newSize),HiWord(newSize),true);
  178.         InvalRect(&window->portRect);
  179.         SetPort(tempPort);
  180.     }
  181. }
  182.  
  183.  
  184. void HandleContent(WindowPtr theWindow,EventRecord *ev)
  185. {
  186.     GrafPtr savePort;
  187.     Point where;
  188.     
  189.     where = ev->where;
  190.     SetPort(theWindow);
  191.     
  192.     if (theWindow != FrontWindow()) {
  193.         SelectWindow(theWindow);
  194.         return;
  195.     }
  196. }
  197.  
  198.  
  199. void HandleUpdates(WindowPtr wind)
  200. {
  201.     GrafPtr savePort;
  202.     
  203.     GetPort(&savePort);
  204.     SetPort(wind);
  205.     BeginUpdate(wind);
  206.     EraseRect(&wind->portRect);
  207.     DrawGrowIcon(wind);
  208.     EndUpdate(wind);
  209.     SetPort(savePort);
  210. }
  211.  
  212.  
  213. void HandleActivates(EventRecord *ev)
  214. {
  215.     if ((ev->modifiers & activeFlag) != 0) {
  216.         DoActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
  217.     }
  218.     else {
  219.         DoDeActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
  220.     }
  221. }
  222.  
  223.  
  224. /* DoActivate: Performs activate tasks */
  225.  
  226. void DoActivate(WindowPtr window,Boolean chFlag)
  227. {
  228.     DrawGrowIcon(window);
  229. }
  230.  
  231.  
  232. /* DoDeActivate: Performs deactivate tasks */
  233.  
  234. void DoDeActivate(WindowPtr window,Boolean chFlag)
  235. {
  236.     DrawGrowIcon(window);
  237. }
  238.  
  239.  
  240. void HandleSREvt(long message)
  241. {
  242.     if ((message >> 24) == 1)
  243.         if ((message & 1) != 0) {
  244.             gInBackground = false;
  245.             SetCursor(&arrow);
  246.             if (FrontWindow()) {  
  247.                 HiliteWindow(FrontWindow(),true);
  248.                 DoActivate(FrontWindow(),true);
  249.             }
  250.         }
  251.         else if (FrontWindow()) {
  252.             gInBackground = true;
  253.             HiliteWindow(FrontWindow(),false);
  254.             DoDeActivate(FrontWindow(),true);
  255.         }
  256. }
  257.  
  258.  
  259.  
  260.  
  261. /* this installs the WDEF patch into a window */
  262.  
  263. void PatchWindowWDEF(WindowPtr window)
  264. {
  265.     WDEFPatchHndl wdefHndl;
  266.     WDEFPatchPtr wdefPatch;
  267.     
  268.     wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
  269.     HLock(wdefHndl);
  270.     wdefPatch = *wdefHndl;
  271.     wdefPatch->oldAddr = ((WindowPeek)window)->windowDefProc;
  272.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  273.     wdefPatch->patchAddr = MyWDEFPatch;
  274.     HUnlock(wdefHndl);
  275.     ((WindowPeek)window)->windowDefProc = (Handle)wdefHndl;
  276. }
  277.  
  278.  
  279. pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param)
  280. {
  281.     WDEFPatchHndl wdPatch;
  282.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  283.     Handle oldWDEF;
  284.     long result;
  285.     Rect ourRect,ourElementRect;
  286.     Point *hitPt;
  287.     Point mouse;
  288.     
  289.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  290.     SetRect(&ourElementRect,ourRect.right-32,ourRect.top+4,ourRect.right-20,ourRect.top+15);
  291.     
  292.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  293.     oldWDEF = (**wdPatch).oldAddr;
  294.     HLock(oldWDEF);
  295.     wdefProc = (void *)*oldWDEF;
  296.     wdefProc = (void *)StripAddress(wdefProc);
  297.     result = (wdefProc)(varCode,window,message,param);
  298.     
  299.     switch (message) {
  300.         case wDraw:
  301.             if (((WindowPeek)window)->visible) {
  302.                 PenNormal();                            // draw our part
  303.                 InsetRect(&ourElementRect,-1,0);
  304.                 EraseRect(&ourElementRect);
  305.                 InsetRect(&ourElementRect,1,0);
  306.                 FrameRect(&ourElementRect);
  307.                 InsetRect(&ourElementRect,2,2);
  308.                 FrameRect(&ourElementRect);
  309.             }
  310.             break;
  311.         case wHit:
  312.             hitPt = (Point *)¶m;                    // hit test our part
  313.             if (PtInRect(*hitPt,&ourElementRect))
  314.                 result =  kOurHit;
  315.             break;
  316.     }
  317.  
  318.     HUnlock(oldWDEF);
  319.     
  320.     return result;
  321. }
  322.  
  323.